package chen.yi.component.mysql.check;

import chen.yi.component.common.exception.BizException;
import chen.yi.component.mysql.enums.TableErrorEnums;
import chen.yi.component.mysql.po.FieldPO;
import chen.yi.component.mysql.po.TablePO;
import chen.yi.component.mysql.utils.TableAttrUtils;
import chen.yi.component.mysql.vo.system.TableEngineVO;
import cn.hutool.core.util.StrUtil;
import lombok.extern.slf4j.Slf4j;

import java.util.List;

import static chen.yi.component.mysql.constant.OperationType.ALTER;
import static chen.yi.component.mysql.constant.OperationType.CREATE;
import static chen.yi.component.mysql.enums.TableErrorEnums.TABLE_FIELD;

/**
 * 表属性校验规则
 *
 * @author huat
 **/
@Slf4j
public final class TableCheckUtils extends BaseCheckUtils {
    private TableCheckUtils() {
    }


    /**
     * 校验表属性以及字段、索引等是否合法
     *
     * @param tablePO 表信息
     */
    public static void checkCreateTableInfo(final TablePO tablePO) {
        checkTableName(tablePO.getName(),CREATE);
        checkTableEngine(tablePO.getEngine(),CREATE);
        checkComment(tablePO.getComment(),CREATE);
        checkField(tablePO.getFields());
        FieldCheckUtils.checkField(tablePO.getFields());
        IndexCheckUtils.checkIndex(tablePO.getIndexes());
        ForeignKeyUtils.checkForeignKey(tablePO.getForeignKeys());
    }
    /**
     * 修改表信息sql查询
     */
    public static void checkModifyTableInfo(final TablePO tablePO) {
        checkTableName(tablePO.getName(),ALTER);
        checkTableEngine(tablePO.getEngine(),ALTER);
        checkComment(tablePO.getComment(),ALTER);
    }

    /**
     * 校验表名
     *
     * @param tableName 表名
     */
    private static void checkTableName(String tableName,final String operationType) {
        if(StrUtil.isBlank(tableName)&&StrUtil.equals(operationType,ALTER)) {
            return;
        }
        if (!NAME_PATTERN.matcher(tableName).matches() || RESERVED_WORDS.contains(tableName.toUpperCase())) {
            throw new BizException(TableErrorEnums.TABLE_NAME.getCode(), String.format(TableErrorEnums.TABLE_NAME.getMessage(), tableName));
        }
    }

    /**
     * 校验表引擎是否合法
     *
     * @param engineName 引擎名
     * @param operationType 操作类型，区分是创建还是修改，修改时字段允许为空
     */
    private static void checkTableEngine(final String engineName,final String operationType) {
        if(StrUtil.isBlank(engineName)&&StrUtil.equals(operationType,ALTER)) {
            return;
        }
        TableEngineVO tableEngine = TableAttrUtils.getTableEngine();
        if (!tableEngine.getTableEngine().contains(engineName)) {
            throw new BizException(TableErrorEnums.ENGINE_TYPE.getCode(), String.format(TableErrorEnums.ENGINE_TYPE.getMessage(), engineName));
        }
    }


    /**
     * 备注校验
     *
     * @param comment 备注内容
     * @param operationType 操作类型，区分是创建还是修改，修改时字段允许为空
     */
    private static void checkComment(String comment,String operationType) {
        if(StrUtil.isBlank(comment)&&StrUtil.equals(operationType,ALTER)) {
            return;
        }
        if (StrUtil.isBlank(comment)) {
            throw new BizException(TableErrorEnums.TABLE_COMMENT.getCode(), TableErrorEnums.TABLE_COMMENT.getMessage());
        }
        if (!COMMENT_PATTERN.matcher(comment).matches()) {
            throw new BizException(TableErrorEnums.COMMENT_CONTENT.getCode(), String.format(TableErrorEnums.COMMENT_CONTENT.getMessage(), comment));
        }
    }

    /**
     * 校验字段是否为空
     * @param fieldPOList
     */
    private static void checkField(final List<FieldPO> fieldPOList) {
        if (fieldPOList == null || fieldPOList.isEmpty()) {
            throw new BizException(TableErrorEnums.TABLE_FIELD.getCode(), TABLE_FIELD.getMessage());
        }
    }

}
